#include "ModRunPrototype.h"
#include <QDebug>

#include "../Output/FactoryOutput.h"

#include "Gof23/Gof_Prototype/DataRun.h"
#include "Gof23/Gof_Prototype/DataWalk.h"

//原型模式的ModRun（Prototype）;
ModRunPrototype::ModRunPrototype()
{
    //模式名称;
    m_strModelName = "原型模式（Prototype）;";
    //模式描述;
    m_strModelDesc = "原型模式：用原型实例指定创建对象的种类，并且通过拷贝这些原型创建新的对象。通俗的讲就是当需要创建一个新的实例化对象时，我们刚好有一个实例化对象，\r\n"
                     "但是已经存在的实例化对象又不能直接使用。这种情况下拷贝一个现有的实例化对象来用，可能会更方便。\r\n\r\n"
                     "以下情形可以考虑使用原型模式：\r\n"
                     "  当new一个对象，非常繁琐复杂时，可以使用原型模式来进行复制一个对象。比如创建对象时，构造函数的参数很多，\r\n"
                     "  而自己又不完全的知道每个参数的意义，就可以使用原型模式来创建一个新的对象，不必去理会创建的过程。\r\n"
                     "  当需要new一个新的对象，这个对象和现有的对象区别不大，我们就可以直接复制一个已有的对象，然后稍加修改。\r\n"
                     "  当需要一个对象副本时，比如需要提供对象的数据，同时又需要避免外部对数据对象进行修改，那就拷贝一个对象副本供外部使用。\r\n"
                     ;
}

//初始化显示模式;
void ModRunPrototype::InitDisplay()
{
    qDebug() << m_strModelName;
    std::shared_ptr<IOutput> pOutPut = FactoryOutput::GetInstance()->CreateDescOutput();
    if (pOutPut)
    {
        std::initializer_list<QString> outList{ m_strModelName,m_strModelDesc};
        pOutPut->OutPut(outList);
    }
}

//返回模式类型;
EnumModRun ModRunPrototype::GetEnum()
{
    return emModRunPrototype;
}

//运行模式;
void ModRunPrototype::ModRun()
{
    std::shared_ptr<IOutput> pOutPut = FactoryOutput::GetInstance()->CreateRunOutput();
    if (pOutPut)
    {
        std::initializer_list<QString> outListStart{ "========原型模式 start:=======" };
        std::initializer_list<QString> outListEnd{ "========原型模式 end:=======" };
        pOutPut->OutPut(outListStart);

        std::unique_ptr<BaseData> dataBase = std::make_unique<DataRun>();
        dataBase->SetData("RunData");

        std::unique_ptr<BaseData> dataBaseClone = dataBase->Clone();

        dataBase->Print();
        dataBaseClone->Print();

        dataBaseClone->SetData("Clone_RunData_Change");

        dataBase->Print();
        dataBaseClone->Print();

        pOutPut->OutPut(outListEnd);
    }

}

InterFaceModRun* ModRunPrototype::CreateMe()
{
    return new ModRunPrototype();
}
